#ifndef _MNurbsIntersector
#define _MNurbsIntersector
//-
// ==========================================================================
// Copyright (C) 1995 - 2007 Autodesk, Inc., and/or its licensors.  All
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its
// licensors,  which is protected by U.S. and Canadian federal copyright law
// and by international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of Autodesk.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL AUTODESK AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
//+
//
// CLASS:    MNurbsIntersector
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES


#include <float.h>
#include <maya/MStatus.h>
#include <maya/MPointArray.h>
#include <maya/MMatrix.h>

// ****************************************************************************
// DECLARATIONS

class MStatus;
class MPointOnNurbs;
class TnurbsSurface;
class MDoubleArray;

// ****************************************************************************
// CLASS DECLARATION (MNurbsIntersector)

//! \ingroup OpenMaya
//! \brief Nurbs intersector. 
/*!
	The MNurbsIntersector class contains methods for efficiently finding
	the closest point to a NURBS surface. A tree-based algorithm is used to
	find the closest point.

	The create() method builds the internal data required for the algorithm.
	As a result, calls to it should be minimized as it is a heavy operation.
	If the NURBS surface or matrix changes, you will need to recreate the
	tree based data to correspond, again using the create() method.

	This class is not threadsafe.
*/
class OPENMAYA_EXPORT MNurbsIntersector
{
public:
	MNurbsIntersector( void );
	virtual			~MNurbsIntersector( void );

	MStatus			create( MObject &nurbsObject,
						const MMatrix &matrix = MMatrix::identity );

	bool			isCreated( void );

	MStatus			getClosestPoint( MPoint& point,
						MPointOnNurbs& nurbsPoint,
						double maxDistance = DBL_MAX );

	MStatus			getIntersects(const MPoint &rayStartingPoint,
									const MVector &alongThisDirection,
									MDoubleArray & uArray, MDoubleArray & vArray,
									MPointArray &points,
									double tolerance);

	MStatus			getIntersect(const MPoint &rayStartingPoint,
									const MVector &alongThisDirection,
									double & u, double & v,
									MPoint &pntOfIntersection,
									double tolerance);

	static const char*	className();

protected:
// No protected members

private:
	void			*instance;
	void			*instanceRay;
	TnurbsSurface	*surf;

	MMatrix			matrix;

	bool			created;
};

// NURBS point information. (OpenMaya) (OpenMaya.py)
//
class OPENMAYA_EXPORT MPointOnNurbs
{
public:
	//
	MPointOnNurbs();
	//
	MPointOnNurbs( const MPointOnNurbs& other );
	//
	MPointOnNurbs&	operator=( const MPointOnNurbs& other );
	//
	MPoint			&getPoint();
	//
	MPoint			&getUV();

private:
	friend class	MNurbsIntersector;
	MPoint			point;
	MPoint			uv;
};

#endif /* __cplusplus */
#endif /* _MNurbsIntersector */
